package com.bungarus.busi;

import com.bungarus.Access;
import com.bungarus.codec.protobuf.MessageProtobuf;
import com.bungarus.event.SessionCreatedEvent;
import com.bungarus.event.SessionTransferedEvent;
import com.bungarus.model.MessageBuilder;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.log4j.Logger;

import java.util.List;

/**
 * Sync the session data to Busi via Transfer
 * Created by tang on 2018/11/13.
 */
@ChannelHandler.Sharable
public class TransferSessionHandler extends ChannelInboundHandlerAdapter {
    Logger logger = Logger.getLogger(TransferSessionHandler.class);
    private final Access access;

    public TransferSessionHandler(Access access) {
        this.access = access;
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if(evt instanceof SessionCreatedEvent){
            SessionCreatedEvent event = (SessionCreatedEvent) evt;
            MessageProtobuf.Message msg = MessageBuilder.buildSessionMessage(access.getIdMaker(), event.getSession(), event.getHeader().getId2());
            //send session info to transfer layer
            //the node lives in transfer cluster will be chosen according to message id % member size of transfer cluster
            List<InnerClient> transferClients = access.getInnerClientList().get(Access.CLUSTER_TAG_TRANSFER);
            long index = Long.parseLong(msg.getHeader().getId()) % transferClients.size();
            InnerClient client = transferClients.get((int)index);

            client.sendMessage(MessageBuilder.buildAccess2TransferMsg(Access.CLUSTER_TAG_TRANSFER, msg),
                    Access.CLUSTER_TAG_TRANSFER);
            ctx.fireUserEventTriggered(new SessionTransferedEvent(event.getSession(), msg.getHeader().getId(), msg.getHeader().getId2()));
        }
        else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }
}